package flixel.input.keyboard;

import flixel.FlxG;

/**
 * A helper class for keyboard input.
 * Provides optimized key checking using direct array access.
 */
class FlxKeyList
{
	#if !FLX_NO_KEYBOARD
	private var checkStatus:Int;
	
	public function new(CheckStatus:Int)
	{
		checkStatus = CheckStatus;
	}
	
	public var A			(get, never):Bool;	inline function get_A()				{ return check(FlxKey.A);			}
	public var B			(get, never):Bool;	inline function get_B()				{ return check(FlxKey.B);			}
	public var C			(get, never):Bool;	inline function get_C()				{ return check(FlxKey.C);			}
	public var D			(get, never):Bool;	inline function get_D()				{ return check(FlxKey.D);			}
	public var E			(get, never):Bool;	inline function get_E()				{ return check(FlxKey.E);			}
	public var F			(get, never):Bool;	inline function get_F()				{ return check(FlxKey.F);			}
	public var G			(get, never):Bool;	inline function get_G()				{ return check(FlxKey.G);			}
	public var H			(get, never):Bool;	inline function get_H()				{ return check(FlxKey.H);			}
	public var I			(get, never):Bool;	inline function get_I()				{ return check(FlxKey.I);			}
	public var J			(get, never):Bool;	inline function get_J()				{ return check(FlxKey.J);			}
	public var K			(get, never):Bool;	inline function get_K()				{ return check(FlxKey.K);			}
	public var L			(get, never):Bool;	inline function get_L()				{ return check(FlxKey.L);			}
	public var M			(get, never):Bool;	inline function get_M()				{ return check(FlxKey.M);			}
	public var N			(get, never):Bool;	inline function get_N()				{ return check(FlxKey.N);			}
	public var O			(get, never):Bool;	inline function get_O()				{ return check(FlxKey.O);			}
	public var P			(get, never):Bool;	inline function get_P()				{ return check(FlxKey.P);			}
	public var Q			(get, never):Bool;	inline function get_Q()				{ return check(FlxKey.Q);			}
	public var R			(get, never):Bool;	inline function get_R()				{ return check(FlxKey.R);			}
	public var S			(get, never):Bool;	inline function get_S()				{ return check(FlxKey.S);			}
	public var T			(get, never):Bool;	inline function get_T()				{ return check(FlxKey.T);			}
	public var U			(get, never):Bool;	inline function get_U()				{ return check(FlxKey.U);			}
	public var V			(get, never):Bool;	inline function get_V()				{ return check(FlxKey.V);			}
	public var W			(get, never):Bool;	inline function get_W()				{ return check(FlxKey.W);			}
	public var X			(get, never):Bool;	inline function get_X()				{ return check(FlxKey.X);			}
	public var Y			(get, never):Bool;	inline function get_Y()				{ return check(FlxKey.Y);			}
	public var Z			(get, never):Bool;	inline function get_Z()				{ return check(FlxKey.Z);			}
	public var ZERO			(get, never):Bool;	inline function get_ZERO()			{ return check(FlxKey.ZERO);		}
	public var ONE			(get, never):Bool;	inline function get_ONE()			{ return check(FlxKey.ONE);			}
	public var TWO			(get, never):Bool;	inline function get_TWO()			{ return check(FlxKey.TWO);			}
	public var THREE		(get, never):Bool;	inline function get_THREE()			{ return check(FlxKey.THREE);		}
	public var FOUR			(get, never):Bool;	inline function get_FOUR()			{ return check(FlxKey.FOUR);		}
	public var FIVE			(get, never):Bool;	inline function get_FIVE()			{ return check(FlxKey.FIVE);		}
	public var SIX			(get, never):Bool;	inline function get_SIX()			{ return check(FlxKey.SIX);			}
	public var SEVEN		(get, never):Bool;	inline function get_SEVEN()			{ return check(FlxKey.SEVEN);		}
	public var EIGHT		(get, never):Bool;	inline function get_EIGHT()			{ return check(FlxKey.EIGHT);		}
	public var NINE			(get, never):Bool;	inline function get_NINE()			{ return check(FlxKey.NINE);		}
	public var PAGEUP		(get, never):Bool;	inline function get_PAGEUP()		{ return check(FlxKey.PAGEUP);		}
	public var PAGEDOWN		(get, never):Bool;	inline function get_PAGEDOWN()		{ return check(FlxKey.PAGEDOWN);	}
	public var HOME			(get, never):Bool;	inline function get_HOME()			{ return check(FlxKey.HOME);		}
	public var END			(get, never):Bool;	inline function get_END()			{ return check(FlxKey.END);			}
	public var INSERT		(get, never):Bool;	inline function get_INSERT()		{ return check(FlxKey.INSERT);		}
	public var ESCAPE		(get, never):Bool;	inline function get_ESCAPE()		{ return check(FlxKey.ESCAPE);		}
	public var MINUS		(get, never):Bool;	inline function get_MINUS()			{ return check(FlxKey.MINUS);		}
	public var PLUS			(get, never):Bool;	inline function get_PLUS()			{ return check(FlxKey.PLUS);		}
	public var DELETE		(get, never):Bool;	inline function get_DELETE()		{ return check(FlxKey.DELETE);		}
	public var BACKSPACE	(get, never):Bool;	inline function get_BACKSPACE()		{ return check(FlxKey.BACKSPACE);	}
	public var LBRACKET		(get, never):Bool;	inline function get_LBRACKET()		{ return check(FlxKey.LBRACKET);	}
	public var RBRACKET		(get, never):Bool;	inline function get_RBRACKET()		{ return check(FlxKey.RBRACKET);	}
	public var BACKSLASH	(get, never):Bool;	inline function get_BACKSLASH()		{ return check(FlxKey.BACKSLASH);	}
	public var CAPSLOCK		(get, never):Bool;	inline function get_CAPSLOCK()		{ return check(FlxKey.CAPSLOCK);	}
	public var SEMICOLON	(get, never):Bool;	inline function get_SEMICOLON()		{ return check(FlxKey.SEMICOLON);	}
	public var QUOTE		(get, never):Bool;	inline function get_QUOTE()			{ return check(FlxKey.QUOTE);		}
	public var ENTER		(get, never):Bool;	inline function get_ENTER()			{ return check(FlxKey.ENTER);		}
	public var SHIFT		(get, never):Bool;	inline function get_SHIFT()			{ return check(FlxKey.SHIFT);		}
	public var COMMA		(get, never):Bool;	inline function get_COMMA()			{ return check(FlxKey.COMMA);		}
	public var PERIOD		(get, never):Bool;	inline function get_PERIOD()		{ return check(FlxKey.PERIOD);		}
	public var SLASH		(get, never):Bool;	inline function get_SLASH()			{ return check(FlxKey.SLASH);		}
	public var NUMPADSLASH	(get, never):Bool;	inline function get_NUMPADSLASH()	{ return check(FlxKey.NUMPADSLASH);	}
	public var GRAVEACCENT	(get, never):Bool;	inline function get_GRAVEACCENT()	{ return check(FlxKey.GRAVEACCENT);	}
	public var CONTROL		(get, never):Bool;	inline function get_CONTROL()		{ return check(FlxKey.CONTROL);		}
	public var ALT			(get, never):Bool;	inline function get_ALT()			{ return check(FlxKey.ALT);			}
	public var SPACE		(get, never):Bool;	inline function get_SPACE()			{ return check(FlxKey.SPACE);		}
	public var UP			(get, never):Bool;	inline function get_UP()			{ return check(FlxKey.UP);			}
	public var DOWN			(get, never):Bool;	inline function get_DOWN()			{ return check(FlxKey.DOWN);		}
	public var LEFT			(get, never):Bool;	inline function get_LEFT()			{ return check(FlxKey.LEFT);		}
	public var RIGHT		(get, never):Bool;	inline function get_RIGHT()			{ return check(FlxKey.RIGHT);		}
	public var TAB			(get, never):Bool;	inline function get_TAB()			{ return check(FlxKey.TAB);			}
#if (flash || js)
	public var F1			(get, never):Bool;	inline function get_F1()			{ return check(FlxKey.F1);			}
	public var F2			(get, never):Bool;	inline function get_F2()			{ return check(FlxKey.F2);			}
	public var F3			(get, never):Bool;	inline function get_F3()			{ return check(FlxKey.F3);			}
	public var F4			(get, never):Bool;	inline function get_F4()			{ return check(FlxKey.F4);			}
	public var F5			(get, never):Bool;	inline function get_F5()			{ return check(FlxKey.F5);			}
	public var F6			(get, never):Bool;	inline function get_F6()			{ return check(FlxKey.F6);			}
	public var F7			(get, never):Bool;	inline function get_F7()			{ return check(FlxKey.F7);			}
	public var F8			(get, never):Bool;	inline function get_F8()			{ return check(FlxKey.F8);			}
	public var F9			(get, never):Bool;	inline function get_F9()			{ return check(FlxKey.F9);			}
	public var F10			(get, never):Bool;	inline function get_F10()			{ return check(FlxKey.F10);			}
	public var F11			(get, never):Bool;	inline function get_F11()			{ return check(FlxKey.F11);			}
	public var F12			(get, never):Bool;	inline function get_F12()			{ return check(FlxKey.F12);			}
	public var NUMPADONE	(get, never):Bool;	inline function get_NUMPADONE()		{ return check(FlxKey.NUMPADONE);	}
	public var NUMPADTWO	(get, never):Bool;	inline function get_NUMPADTWO()		{ return check(FlxKey.NUMPADTWO);	}
	public var NUMPADTHREE	(get, never):Bool;	inline function get_NUMPADTHREE()	{ return check(FlxKey.NUMPADTHREE);	}
	public var NUMPADFOUR	(get, never):Bool;	inline function get_NUMPADFOUR()	{ return check(FlxKey.NUMPADFOUR);	}
	public var NUMPADFIVE	(get, never):Bool;	inline function get_NUMPADFIVE()	{ return check(FlxKey.NUMPADFIVE);	}
	public var NUMPADSIX	(get, never):Bool;	inline function get_NUMPADSIX()		{ return check(FlxKey.NUMPADSIX);	}
	public var NUMPADSEVEN	(get, never):Bool;	inline function get_NUMPADSEVEN()	{ return check(FlxKey.NUMPADSEVEN);	}
	public var NUMPADEIGHT	(get, never):Bool;	inline function get_NUMPADEIGHT()	{ return check(FlxKey.NUMPADEIGHT);	}
	public var NUMPADNINE	(get, never):Bool;	inline function get_NUMPADNINE()	{ return check(FlxKey.NUMPADNINE);	}
	public var NUMPADZERO	(get, never):Bool;	inline function get_NUMPADZERO()	{ return check(FlxKey.NUMPADZERO);	}
	public var NUMPADMINUS	(get, never):Bool;	inline function get_NUMPADMINUS()	{ return check(FlxKey.NUMPADMINUS);	}
	public var NUMPADPLUS	(get, never):Bool;	inline function get_NUMPADPLUS()	{ return check(FlxKey.NUMPADPLUS);	}
	public var NUMPADPERIOD	(get, never):Bool;	inline function get_NUMPADPERIOD()	{ return check(FlxKey.NUMPADPERIOD);}
#end
	
	public var ANY(get, never):Bool; 
	
	private function get_ANY():Bool
	{
		var key:FlxKey = null;
		var keyCode:Int = FlxKeyboard.TOTAL;
		while (keyCode-- >= 0)
		{
			key = FlxG.keys._keyList[keyCode];
			if (key != null)
			{
				if (check(keyCode))
				{
					return true;
				}
			}
		}
		
		return false;
	}
	
	public inline function check(keyCode:Int):Bool
	{
		return FlxG.keys.checkStatus(keyCode, checkStatus);
	}
	#end
}